using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Highlighting;

namespace WpfApp3.ViewModels;

using System.Diagnostics;
using System.Net.Http;
using System.Text;
using System.Windows;
using WpfApp3.Helpers;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.ComponentModel;
using System.Collections.ObjectModel;
using WpfApp3.Model;

public partial class RequestViewModel : ObservableObject
{
    [ObservableProperty] private ObservableCollection<KeyValuePair> _headers = [];
    [ObservableProperty] private ObservableCollection<KeyValuePair> _parameters = [];

    [ObservableProperty] private string _url = "http://";
    [ObservableProperty] private TextDocument _Document = new();

    [ObservableProperty] private string _response = "";

    [ObservableProperty] private RequestMethod _selectedRequestMethod = RequestMethod.GET;
    [ObservableProperty] private string _selectedRequestBodyType = "application/json";

    [ObservableProperty] private ObservableCollection<RequestHistory> _requestHistories = [];
    [ObservableProperty] private int _selectedRequestHistoryIndex;
    [ObservableProperty] private int _selectedParametersIndex;
    [ObservableProperty] private int _selectedHeadersIndex;
    [ObservableProperty] private IHighlightingDefinition _highlightingDefinition;

    public RequestMethod[] RequestMethods { get; } = Enum.GetValues<RequestMethod>();
    public string[] RequestBodyTypes { get; } = new[] { "application/json", "text/plain" };


    public RequestViewModel()
    {
        var hlManager = HighlightingManager.Instance;
        HighlightingDefinition = hlManager.GetDefinitionByExtension(".json");
    }
    
    [RelayCommand]
    private void AddHeader()
    {
        Headers.Add(new KeyValuePair());
    }

    [RelayCommand]
    private void AddParameter()
    {
        Parameters.Add(new KeyValuePair());
    }

    [RelayCommand]
    private async Task SendRequest()
    {
        var client = new HttpClient();
        client.DefaultRequestHeaders.Clear();
        var requestMethod = SelectedRequestMethod.ToString(); // 获取用户选择的请求类型
        var requestBody = Document.Text;
        var content = new StringContent(requestBody, Encoding.UTF8, SelectedRequestBodyType);
        var httpRequest = new HttpRequestMessage(new HttpMethod(requestMethod), Url)
        {
            Content = content
        };
        foreach (var header in Headers)
        {
            httpRequest.Headers.Add(header.Key, header.Value);
        }

        httpRequest.RequestUri = new UriBuilder(httpRequest.RequestUri)
        {
            Query = string.Join("&",
                Parameters.Select(kv => $"{Uri.EscapeDataString(kv.Key)}={Uri.EscapeDataString(kv.Value)}"))
        }.Uri;

        var history = new RequestHistory
        {
            Url = Url,
            Method = SelectedRequestMethod,
            Date = new DateTime(),
            Headers = Headers.ToArray(),
            Parameters = Parameters.ToArray(),
            Body = requestBody
        };
        var stopwatch = Stopwatch.StartNew();
        try
        {
            var httpResponse = await client.SendAsync(httpRequest);
            stopwatch.Stop();
            Response = await httpResponse.Content.ReadAsStringAsync();
            if (FormatHelper.IsJsonObject(Response))
            {
                Response = FormatHelper.FormatJsonObject(Response);
            }
            else if (FormatHelper.IsJsonArray(Response))
            {
                Response = FormatHelper.FormatJsonArray(Response);
            }
            else if (FormatHelper.IsXml(Response))
            {
                Response = FormatHelper.FormatXml(Response);
            }

            history.Response = httpResponse.StatusCode.ToString();
        }
        catch (HttpRequestException ex)
        {
            stopwatch.Stop();
            Response = $"Http Error: {ex.Message}";
            history.Response = Response;
        }
        catch (Exception ex)
        {
            stopwatch.Stop();
            // 处理异常
            Response = $"Error: {ex.Message}";
            history.Response = Response;
        }

        history.ResponseTime = $"{stopwatch.Elapsed.Milliseconds}ms";
        RequestHistories.Add(history);
    }

    [RelayCommand]
    private void ClearRequestBody()
    {
        Document.Text = "";
    }

    [RelayCommand]
    private void ApplyRequestHistory()
    {
        var history = RequestHistories[SelectedRequestHistoryIndex];
        Parameters = new(history.Parameters);
        Headers = new(history.Headers);
        SelectedRequestMethod = history.Method;
        Url = history.Url;
        Document.Text = history.Body;
    }

    [RelayCommand]
    private void DeleteSelectedHistory()
    {
        RequestHistories.RemoveAt(SelectedRequestHistoryIndex);
    }

    [RelayCommand]
    private void DeleteAllHistory()
    {
        if (MessageBox.Show("确定要删除吗",
                "Caution",
                MessageBoxButton.YesNo,
                MessageBoxImage.Question) == MessageBoxResult.Yes)
        {
            RequestHistories.Clear();
        }
    }

    [RelayCommand]
    private void DeleteSelectedRequestParameters()
    {
        Parameters.RemoveAt(SelectedParametersIndex);
    }

    [RelayCommand]
    private void DeleteSelectedRequestHeaders()
    {
        Headers.RemoveAt(SelectedHeadersIndex);
    }

    [RelayCommand]
    private void DeleteAllRequestParameters()
    {
        if (MessageBox.Show("确定要删除吗",
                "Caution",
                MessageBoxButton.YesNo,
                MessageBoxImage.Question) == MessageBoxResult.Yes)
        {
            Parameters.Clear();
        }
    }

    [RelayCommand]
    private void DeleteAllRequestHeaders()
    {
        if (MessageBox.Show("确定要删除吗",
                "Caution",
                MessageBoxButton.YesNo,
                MessageBoxImage.Question) == MessageBoxResult.Yes)
        {
            Headers.Clear();
        }
    }


    [RelayCommand]
    private void CopyResponse()
    {
        Clipboard.SetText(Response);
        MessageBox.Show("复制成功");
    }
}